package org.hk.proxy.server.container;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.hk.proxy.common.container.Container;
import org.hk.proxy.server.channel.HttpRequestHandler;
import org.hk.proxy.server.constant.ProjectConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ExecutionException;

public class WebServerContainer implements Container {
    private static Logger log = LoggerFactory.getLogger(WebServerContainer.class);
    private NioEventLoopGroup serverWorkerGroup;
    private NioEventLoopGroup serverBossGroup;
    public WebServerContainer() {
        this.serverWorkerGroup = new NioEventLoopGroup(2);
        this.serverBossGroup = new NioEventLoopGroup(5);
    }
    @Override
    public void start() throws ExecutionException, InterruptedException {
        ServerBootstrap httpServerBootstrap = new ServerBootstrap();
        httpServerBootstrap.group(serverBossGroup, serverWorkerGroup).channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch){
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast(new HttpServerCodec());
                        pipeline.addLast(new HttpObjectAggregator(8 * 1024 * 1024));
                        pipeline.addLast(new ChunkedWriteHandler());
                        pipeline.addLast(new HttpRequestHandler());
                    }
                });
        httpServerBootstrap.bind(ProjectConfig.config.getWebServerConfig().getIp(),
                ProjectConfig.config.getWebServerConfig().getPort()).get();
        log.info("http server start on port " +  ProjectConfig.config.getWebServerConfig().getPort());
    }
    @Override
    public void stop() {
        this.serverWorkerGroup.shutdownGracefully();
        this.serverBossGroup.shutdownGracefully();
    }
}
